import _ from 'lodash'
// import useClipboard from 'vue-clipboard3'
import printJs from 'print-js'
import html2Canvas from 'html2canvas'
import * as XLSX from 'xlsx'
import $element from './element'
import $storage from '@/utils/storage'
import $config from '@/utils/config'
import $time from '@/utils/time'

export default {
  // 生成UUID
  createUUID() {
    const dg = new Date(1582, 10, 15, 0, 0, 0, 0)
    const dc = new Date()
    const t = dc.getTime() - dg.getTime()
    const tl = this.getIntegerBits(t, 0, 31)
    const tm = this.getIntegerBits(t, 32, 47)
    const thv = this.getIntegerBits(t, 48, 59) + '1'
    const csar = this.getIntegerBits(this.rand(4095), 0, 7)
    const csl = this.getIntegerBits(this.rand(4095), 0, 7)
    const n =
      this.getIntegerBits(this.rand(8191), 0, 7) +
      this.getIntegerBits(this.rand(8191), 8, 15) +
      this.getIntegerBits(this.rand(8191), 0, 7) +
      this.getIntegerBits(this.rand(8191), 8, 15) +
      this.getIntegerBits(this.rand(8191), 0, 15)
    return tl + tm + thv + csar + csl + n
  },

  getIntegerBits(val: any, start: any, end: any) {
    const base16 = val.toString(16).toUpperCase()
    // eslint-disable-next-line no-array-constructor
    const quadArray = new Array()
    let quadString = ''
    let i = 0
    for (i = 0; i < base16.length; i++) {
      quadArray.push(base16.substring(i, i + 1))
    }
    for (i = Math.floor(start / 4); i <= Math.floor(end / 4); i++) {
      if (!quadArray[i] || quadArray[i] === '') quadString += '0'
      else quadString += quadArray[i]
    }
    return quadString
  },

  rand(max: any) {
    return Math.floor(Math.random() * (max + 1))
  },

  /**
   * 判断两个对象是否相同
   * @param rowA 要比较的对象一
   * @param rowB 要比较的对象二
   * @returns 相同返回 true，反之则反
   */
  isObjectValueEqual(rowA: { [key: string]: any }, rowB: { [key: string]: any }) {
    return _.isMatchWith(rowA, rowB, (a, b) => {
      if (a && typeof a === 'object' && b && typeof b === 'object') {
        return a.length === b.length
      } else {
        _.isEmpty(a) && _.isEmpty(b) ? true : a === b
      }
    })
  },

  /**
   * 判断是否是移动端
   */
  isMobile() {
    if (
      navigator.userAgent.match(
        /('phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone')/i
      )
    ) {
      return true
    } else {
      return false
    }
  },

  /**
   * 点击复制文本
   */
  copyText(text: string) {
    const { toClipboard } = useClipboard()

    return new Promise((resolve, reject) => {
      try {
        toClipboard(text)
        $element.toast('复制成功', 'success')
        resolve(text)
      } catch (e) {
        $element.toast('复制失败', 'error')
        reject(e)
      }
    })
  },

  /**
   * 生成图片
   */
  getJpeg(dom: any, type = 'image/jpeg') {
    return new Promise((resolve) => {
      html2Canvas(dom).then((canvas) => {
        const jpeg = canvas.toDataURL(type)
        resolve(jpeg)
      })
    })
  },

  /**
   * 打印
   */
  async print(dom: any, type: any) {
    const url: any = await this.getJpeg(dom)
    // printJs(url, type)
    printJs({
      printable: url,
      type: type,
      style: '@page {margin:0 10mm};' // 打印时去掉眉页眉尾
      // targetStyles: ['*'],
      // style: '@page {margin:0 10mm};' // 可选-打印时去掉眉页眉尾
      // ignoreElements: params.ignore || [], // ['no-print']
      // properties: params.properties || null
    })
  },

  /**
   * 导出Excel
   */
  export(titleList: any, data: any, cols: any, name: string, sheetName: string) {
    const list = data.map((item: any) => {
      const obj = {} as any
      for (const k in item) {
        if (titleList[k]) {
          obj[titleList[k]] = item[k]
        }
      }
      return obj
    })

    const ws = XLSX.utils.json_to_sheet(list)
    ws['!cols'] = cols

    const wb = XLSX.utils.book_new()
    XLSX.utils.book_append_sheet(wb, ws, sheetName)
    XLSX.writeFile(wb, name + '.xlsx')
  },

  // 导入Excel
  import(file: any) {
    return new Promise((resolve) => {
      const reader = new FileReader()
      reader.readAsArrayBuffer(file)
      reader.onload = (e: any) => {
        const data = e.target.result
        const workbook = XLSX.read(data, { type: 'binary', cellDates: true })
        const wsname = workbook.SheetNames[0]
        const outdata = XLSX.utils.sheet_to_json(workbook.Sheets[wsname])
        resolve(outdata)
      }
    })
  },

  // 追加key
  appendKey(data: any) {
    return Object.assign(data, {
      key: $storage.getSession('key')
    })
  },

  downloadFile(url: any, fileName: string = '文件名称', type: string = '.png') {
    const link = document.createElement('a')
    link.style.display = 'none'
    link.href = url
    link.setAttribute('download', fileName + type)
    document.body.appendChild(link)
    link.click()
  },

  //
  getImage(blob: any) {
    const data = new Blob([blob], {
      type: 'application/jpg;charset=utf-8'
    })

    return window.URL.createObjectURL(data)
  },

  // 获取静态图片资源
  getImageUrl(name: string) {
    return new URL(`../assets/${name}`, import.meta.url).href
  },

  // 判断坐标点是否在区域内
  isPointInPolygon(point: any, polygon: any) {
    const N = polygon.length // pts [{lat:xxx,lng:xxx},{lat:xxx,lng:xxx}] [[lat:xxx,lng:xxx],[lat:xxx,lng:xxx]]
    const boundOrVertex = false // 如果点位于多边形的顶点或边上，也算做点在多边形内，直接返回true
    let intersectCount = 0 // cross points count of x
    const precision = 2e-10 // 浮点类型计算时候与0比较时候的容差
    let p1, p2 // neighbour bound vertices
    // const p = point // point {lat:xxx,lng:xxx} [data.lon, data.lat] 108.91573541790773,34.2233252807995

    p1 = polygon[0] // left vertex
    for (var i = 1; i <= N; ++i) {
      // check all rays
      if (point[1] === p1[1] && point[0] === p1[0]) {
        return boundOrVertex // p is an vertex
      }
      p2 = polygon[i % N] // right vertex
      if (point[1] < Math.min(p1[1], p2[1]) || point[1] > Math.max(p1[1], p2[1])) {
        // ray is outside of our interests
        p1 = p2
        continue // next ray left point
      }
      if (point[1] > Math.min(p1[1], p2[1]) && point[1] < Math.max(p1[1], p2[1])) {
        // ray is crossing over by the algorithm (common part of)
        if (point[0] <= Math.max(p1[0], p2[0])) {
          // x is before of ray
          if (p1[1] === p2[1] && point[0] >= Math.min(p1[0], p2[0])) {
            // overlies on a horizontal ray
            return boundOrVertex
          }
          if (p1[0] === p2[0]) {
            // ray is vertical
            if (p1[0] === point[0]) {
              // overlies on a vertical ray
              return boundOrVertex
            } else {
              // before ray
              ++intersectCount
            }
          } else {
            // cross point on the left side
            var xinters = ((point[1] - p1[1]) * (p2[0] - p1[0])) / (p2[1] - p1[1]) + p1[0] // cross point of lng
            if (Math.abs(point[0] - xinters) < precision) {
              // overlies on a ray
              return boundOrVertex
            }
            if (point[0] < xinters) {
              // before ray
              ++intersectCount
            }
          }
        }
      } else {
        // special case when ray is crossing through the vertex
        if (point[1] === p2[1] && point[0] <= p2[0]) {
          // p crossing over p2
          var p3 = polygon[(i + 1) % N] // next vertex
          if (point[1] >= Math.min(p1[1], p3[1]) && point[1] <= Math.max(p1[1], p3[1])) {
            // point[1] lies betweenp1[1] & p3[1]
            ++intersectCount
          } else {
            intersectCount += 2
          }
        }
      }
      p1 = p2 // next ray left point
    }
    if (intersectCount % 2 === 0) {
      // 偶数在多边形外
      return false
    } else {
      // 奇数在多边形内
      return true
    }
  },

  getRandomColor(opacity: Number = 1) {
    const col =
      'rgb' +
      '(' +
      Math.ceil(Math.random() * 255) +
      ',' +
      Math.ceil(Math.random() * 255) +
      ',' +
      Math.ceil(Math.random() * 255) +
      ',' +
      opacity +
      ')'
    return col
  },

  // 返回事件类型
  getEventType(type: any) {
    const typeName = _.find($config.eventType, (o) => {
      return o.value === Number(type)
    })
    return typeName
  },

  // 返回相位名称
  getPhase(id: any) {
    const data = _($config.phaseList).find((item: any) => {
      return item.value === id
    })

    return data
  },

  // 返回灯态图片
  replaceStr_1(key: any, data: any, initData: any) {
    if (data.left === '0001') {
      initData.splice(1, 1, 1)
    }
    if (data.straight === '0001') {
      initData.splice(2, 1, 1)
    }
    if (initData.includes(1)) {
      return key + initData.join('')
    }
  },
  getLightImgForWS(data: any, lightType: any) {
    if (data.type === '0021') {
      const imageUrl = []
      const [detail] = data.data.detail.filter((item_1: any) => item_1.phase_no === data.data.current)
      for (const key in detail.def) {
        if (Number(key) <= 4) {
          const strImg = this.replaceStr_1(key, detail.def[key], [0, 0, 0, 0])
          if (strImg) {
            imageUrl.push(strImg)
          }
        }
      }
      let newUrl = ''
      if (lightType === 1) {
        newUrl = this.getImageUrl('light/' + imageUrl.join('-') + '.png')
      } else if (lightType === 2) {
        newUrl = this.getImageUrl('light_tint/' + imageUrl.join('-') + '.png')
      } else if (lightType === 3) {
        newUrl = this.getImageUrl('light_tint_2/' + imageUrl.join('-') + '.png')
      } else if (newUrl.includes('undefined')) {
        newUrl = this.getImageUrl('light/abnormal_light.png')
      }
      return newUrl
    }
  },
  getLightImgForAPI(data: any, lightType: any) {
    data.forEach((item: any) => {
      item.detail.forEach((item_1: any) => {
        item['phase_no_' + item_1.phase_no] = item_1.time_length + '秒 -- ' + item_1.name
        // 绘制相位灯态
        const imageUrl = []
        for (const key in item_1.def) {
          if (Number(key) <= 4) {
            const strImg = this.replaceStr_1(key, item_1.def[key], [0, 0, 0, 0])
            if (strImg) {
              imageUrl.push(strImg)
            }
          }
        }
        let url = ''
        if (imageUrl.length > 0) {
          if (lightType === 1) {
            url = this.getImageUrl('light/' + imageUrl.join('-') + '.png')
          } else if (lightType === 2) {
            url = this.getImageUrl('light_tint/' + imageUrl.join('-') + '.png')
          } else if (lightType === 3) {
            url = this.getImageUrl('light_tint_2/' + imageUrl.join('-') + '.png')
          }
          item_1['imgurl'] = url
        } else {
          url = this.getImageUrl('light/abnormal_light.png')
          item_1['imgurl'] = url
        }
      })
      item['t_end'] = $time.formatTimeStamp(item.t_start + item.time_length)
      item['t_start'] = $time.formatTimeStamp(item.t_start)
    })
    return data
  }
}
